package progress.exa30_1.demo;

import java.util.*;
import java.lang.reflect.*;

public class ReflectionTest {
    public static void main(String[] args) {
        String name;//用于存储类名
        if (args.length > 0) {
            name = args[0];
        } else {
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g：java.util.Date): ");
            name = in.next();
        }
        try {
            Class cl = Class.forName(name);//得到此类的Class实例
            Class supercl = cl.getSuperclass();//得到其父类的Class对象

            /*返回cl修饰符的字符串表示
              int getModifiers();返回一个整数，描述调用对象的修饰符
              Modifier.toString(int modifiers);返回此修饰符的字符串表示
             */
            String modifiers = Modifier.toString(cl.getModifiers());

            //打印出这个类的声明
            if (modifiers.length() > 0) System.out.print(modifiers + " ");
            System.out.print("class " + name);
            //打印它继承的父类
            if (supercl != null && supercl != Object.class) System.out.print(" extends "
                    + supercl.getName());
            //打印花括号
            System.out.print("\n{\n");
            //打印cl的构造方法
            printConstructors(cl);
            System.out.println();
            //打印cl的其他方法
            printMethods(cl);
            System.out.println();
            //cl中的所有域
            printFields(cl);
            System.out.println("}");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }


    /**
     * 打印出参数cl中描述的构造器信息
     * @param cl
     */
    public static void printConstructors(Class cl) {
        //得到包含cl中的全部构造器的一个Constructor对象数组
        Constructor[] constructors = cl.getDeclaredConstructors();

        for (Constructor c : constructors) {
            String name = c.getName();
            System.out.print("   ");
            String modifiers = Modifier.toString(c.getModifiers());
            if (modifiers.length() > 0) System.out.print(modifiers + " ");
            System.out.print(name + "(");

            // Class[] getParameterTypes(); 返回一个Class对象数组，其中各个对象表示参数的类型
            Class[] paramTypes = c.getParameterTypes();
            for (int j = 0; j < paramTypes.length; j++) {
                if (j > 0) System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }

    /**
     * 打印出cl描述的类的方法信息
     * @param cl
     */
    public static void printMethods(Class cl) {
        //得到这个类中的全部方法数组
        Method[] methods = cl.getDeclaredMethods();

        for (Method m : methods) {
            Class retType = m.getReturnType();//返回一个用于表示返回类型的Class对象
            String name = m.getName();

            System.out.print("   ");
            // 打印修饰符，返回类型和方法名
            String modifiers = Modifier.toString(m.getModifiers());
            if (modifiers.length() > 0) System.out.print(modifiers + " ");
            System.out.print(retType.getName() + " " + name + "(");

            // 打印参数部分
            Class[] paramTypes = m.getParameterTypes();
            for (int j = 0; j < paramTypes.length; j++)
            {
                if (j > 0) System.out.print(", ");
                System.out.print(paramTypes[j].getName());
            }
            System.out.println(");");
        }
    }

    /**
     * 打印出cl描述的类的属性信息
     * @param cl
     */
    public static void printFields(Class cl){
        Field[] fields = cl.getDeclaredFields();//返回包含Field对象的数组，这些对象对应这个类的全部字段

        for (Field f : fields) {
            Class type = f.getType();
            String name = f.getName();
            System.out.print("   ");
            String modifiers = Modifier.toString(f.getModifiers());
            if (modifiers.length() > 0) System.out.print(modifiers + " ");
            System.out.println(type.getName() + " " + name + ";");
        }
    }
}
